import pytest
import requests
import json
from unittest.mock import patch, MagicMock
import time
import random

# 配置信息
API_URL = "https://cvm.tencentcloudapi.com/"
REGION = "ap-guangzhou"
SECRET_ID = "your-secret-id"
SECRET_KEY = "your-secret-key"


def generate_signature(params, SECRET_KEY):
    """生成签名（模拟实现）"""
    return "mock-signature"


def send_request(action, params=None):
    """发送API请求（模拟实现）"""
    if params is None:
        params = {}
    common_params = {
        "Action": action,
        "Version": "2017-03-12",
        "Region": REGION,
        "SecretId": SECRET_ID,
        "Timestamp": int(time.time()),
        "Nonce": random.randint(1, 1000000),
        "SignatureMethod": "HmacSHA256"
    }
    all_params = {**common_params, **params}
    all_params["Signature"] = generate_signature(all_params, SECRET_KEY)

    response = requests.post(API_URL, data=all_params)
    return response.json()


class TestModifyInstancesProject:
    @patch('requests.post')
    def test_success(self, mock_post):
        """测试成功修改实例所属项目"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {
            "InstanceIds": ["ins-123456"],
            "ProjectId": 123
        }
        result = send_request("ModifyInstancesProject", params)

        assert "Response" in result
        assert "RequestId" in result["Response"]

    @patch('requests.post')
    def test_internal_error(self, mock_post):
        """测试内部错误"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InternalServerError",
                    "Message": "操作内部错误"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-123456"], "ProjectId": 123}
        result = send_request("ModifyInstancesProject", params)
        assert result["Response"]["Error"]["Code"] == "InternalServerError"

    @patch('requests.post')
    def test_invalid_instance_id(self, mock_post):
        """测试无效实例ID"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidInstanceId.NotFound",
                    "Message": "实例不存在"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["invalid-id"], "ProjectId": 123}
        result = send_request("ModifyInstancesProject", params)
        assert result["Response"]["Error"]["Code"] == "InvalidInstanceId.NotFound"

    @patch('requests.post')
    def test_instance_state_not_supported(self, mock_post):
        """测试实例状态不支持修改项目"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidInstanceState",
                    "Message": "实例状态不支持此操作"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-invalid-state"], "ProjectId": 123}
        result = send_request("ModifyInstancesProject", params)
        assert result["Response"]["Error"]["Code"] == "InvalidInstanceState"

    @patch('requests.post')
    def test_missing_instance_id(self, mock_post):
        """测试缺少实例ID参数"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "MissingParameter.InstanceIds",
                    "Message": "缺少实例ID参数"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"ProjectId": 123}
        result = send_request("ModifyInstancesProject", params)
        assert result["Response"]["Error"]["Code"] == "MissingParameter.InstanceIds"

    @patch('requests.post')
    def test_missing_project_id(self, mock_post):
        """测试缺少项目ID参数"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "MissingParameter.ProjectId",
                    "Message": "缺少项目ID参数"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-123456"]}
        result = send_request("ModifyInstancesProject", params)
        assert result["Response"]["Error"]["Code"] == "MissingParameter.ProjectId"

    @patch('requests.post')
    def test_invalid_project_id(self, mock_post):
        """测试无效项目ID"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidProjectId.NotFound",
                    "Message": "项目不存在"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-123456"], "ProjectId": -1}
        result = send_request("ModifyInstancesProject", params)
        assert result["Response"]["Error"]["Code"] == "InvalidProjectId.NotFound"

    @patch('requests.post')
    def test_operation_conflict(self, mock_post):
        """测试操作冲突"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "OperationDenied.InstanceOperationInProgress",
                    "Message": "实例正在执行其他操作，请稍后再试"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-in-progress"], "ProjectId": 123}
        result = send_request("ModifyInstancesProject", params)
        assert result["Response"]["Error"]["Code"] == "OperationDenied.InstanceOperationInProgress"

    @patch('requests.post')
    def test_instance_count_exceeded(self, mock_post):
        """测试实例数量超过限制"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "InvalidParameterValue.ExceedMaxCount",
                    "Message": "实例数量超过限制"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-" + str(i) for i in range(101)], "ProjectId": 123}  # 假设限制为100个
        result = send_request("ModifyInstancesProject", params)
        assert result["Response"]["Error"]["Code"] == "InvalidParameterValue.ExceedMaxCount"

    @patch('requests.post')
    def test_unauthorized_operation(self, mock_post):
        """测试未授权操作"""
        mock_response = MagicMock()
        mock_response.json.return_value = {
            "Response": {
                "Error": {
                    "Code": "UnauthorizedOperation",
                    "Message": "未授权的操作"
                },
                "RequestId": "1234567890"
            }
        }
        mock_post.return_value = mock_response

        params = {"InstanceIds": ["ins-123456"], "ProjectId": 123}
        result = send_request("ModifyInstancesProject", params)
        assert result["Response"]["Error"]["Code"] == "UnauthorizedOperation"


# 启动测试函数
def run_tests():
    pytest.main([__file__, "-v", "-s"])


if __name__ == "__main__":
    run_tests()    